﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;

namespace BigNumber
{
  [Serializable]
  public class ForewardSkipListNode<T>
    where T : class
  {

    public T Data { get; private set; }
    private ForewardSkipListNode<T> m_Next;
    private object m_Locker = new object();
    public ForewardSkipListNode<T> Next
    {
      get
      {
        lock (m_Locker)
        {
          if (m_Next == null) return null;
          return new ForewardSkipListNode<T>(m_Next);
        }
      }
      internal set
      {
        lock (m_Locker)
        {
          m_Next = value;
        }
      }
    }

    internal ForewardSkipListNode(T data)
    {
      m_Next = null;
      Data = data;
    }

    internal ForewardSkipListNode(ForewardSkipListNode<T> node)
    {
      lock (node.m_Locker)
      {
        m_Next = node.m_Next;
        Data = node.Data;
      }
    }

    public static ForewardSkipListNode<T> operator ++(ForewardSkipListNode<T> node)
    {
      return node.Next;
    }
  }

  [Serializable]
  public class ForewardSkipList<T>
    where T : class, IComparable<T>
  {
    public int Count { get; private set; }

    private ForewardSkipListNode<T> m_Head;
    private ForewardSkipListNode<T> m_Tail; // This is a pointer to the last item
    public ForewardSkipList()
    {
      m_Head = new ForewardSkipListNode<T>((T)null);
      m_Tail = m_Head;
    }

    public ForewardSkipListNode<T> Add(T data)
    {
      ForewardSkipListNode<T> result = new ForewardSkipListNode<T>(data);

      m_Tail.Next = result;
      m_Tail = result;
      Count++;
      return new ForewardSkipListNode<T>(result);
    }

    public ForewardSkipListNode<T> First
    {
      get
      {
        if (Count == 0) return null;
        return new ForewardSkipListNode<T>(m_Head.Next);
      }
    }

    public ForewardSkipListNode<T> Last
    {
      get
      {
        if (Count == 0) return null;
        return new ForewardSkipListNode<T>(m_Tail);
      }
    }
    
  }
}
